package com.asiainfo.dacp.datastash.broker.flow.core.repo;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.asiainfo.dacp.datastash.broker.core.BrokerContext;
import com.asiainfo.dacp.datastash.broker.core.enums.UnitTaskStateEnum;
import com.asiainfo.dacp.datastash.broker.core.vo.StashUnitTask;
import com.asiainfo.dacp.datastash.broker.flow.core.domain.Flow;
import com.asiainfo.dacp.datastash.orm.dao.log.DataStashUnitTaskEventLogDao;
import com.asiainfo.dacp.datastash.orm.dao.state.DataStashUnitTaskStateLogDao;
import com.asiainfo.dacp.datastash.orm.po.log.DataStashUnitTaskEventLogPo;
import com.asiainfo.dacp.datastash.orm.po.state.DataStashUnitTaskStateLogPo;
import com.asiainfo.dacp.util.BeanConvertUtils;
import com.asiainfo.dacp.util.JsonHelper;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;

@Repository
public class TaskStateRepository {
	@Autowired
	private DataStashUnitTaskStateLogDao stateDao;

	@Autowired
	private DataStashUnitTaskEventLogDao logDao;

	public void create(Flow flow) {
		Preconditions.checkNotNull(flow);
		Map<String, StashUnitTask> taskMap = flow.getTasks();
		Collection<StashUnitTask> tasks = taskMap.values();

		List<DataStashUnitTaskStateLogPo> result = Lists.newArrayList();
		for (StashUnitTask task : tasks) {
			DataStashUnitTaskStateLogPo taskStatePo = new DataStashUnitTaskStateLogPo(task.getTaskProcId(),
					task.getUnitProcId(), task.getUnitCode(), task.getBatchNo(), UnitTaskStateEnum.INIT.value());
			String taskStepsStr = JsonHelper.getInstance().write(task.getTaskSteps());
			taskStatePo.setTaskSteps(taskStepsStr);
			taskStatePo.setTaskType(task.getTaskType());
			taskStatePo.setNextTaskProcIds(JsonHelper.getInstance().write(task.getNextTaskProcIds()));
			taskStatePo.setPreTaskProcIds(JsonHelper.getInstance().write(task.getPreTaskProcIds()));
			
			taskStatePo.setTaskContent(JsonHelper.getInstance().write(task.getTaskContent()));
			taskStatePo.setCreateDt(new Date());
			taskStatePo.setBrokerId(BrokerContext.getInstance().getBrokerId());
			taskStatePo.setBrokerIp(BrokerContext.getInstance().getBrokerIp()); 
			
			taskStatePo.setMessage("单元任务创建");
			result.add(taskStatePo);
		}

		stateDao.save(result); 
		logDao.save(transform(result));
	}
	


	private List<DataStashUnitTaskEventLogPo> transform(List<DataStashUnitTaskStateLogPo> statePos) {
		
		List<DataStashUnitTaskEventLogPo> rst = Lists.newArrayList();
		for(DataStashUnitTaskStateLogPo statePo: statePos){
			String taskProcId = statePo.getTaskProcId();
			DataStashUnitTaskEventLogPo logPo = logDao.findFirstByTaskProcIdOrderByCreateDtDesc(taskProcId);
			if(logPo != null){
				if(logPo.getState().equals(statePo.getState())){
					BeanUtils.copyProperties(statePo, logPo);
				}
			}
			logPo = BeanConvertUtils.copyBean(statePo, DataStashUnitTaskEventLogPo.class);
			rst.add(logPo);
		}
		return rst;
	}

	public void update(Flow flow) {
		Map<String, StashUnitTask> taskMap = flow.getTasks();
		Preconditions.checkNotNull(taskMap);
		Collection<StashUnitTask> tasks = taskMap.values();
		
		List<DataStashUnitTaskStateLogPo> result = Lists.newArrayList();
		for (StashUnitTask task : tasks) {
			DataStashUnitTaskStateLogPo taskStatePo = stateDao.findOne(task.getTaskProcId());
			Preconditions.checkNotNull(taskStatePo, "数据库状态任务和Flow内容有差别，需进行同步.");
			taskStatePo.setBrokerId(task.getBrokerId());
			taskStatePo.setBrokerIp(task.getBrokerIp());
			taskStatePo.setLastupd(new Date());
			taskStatePo.setState(task.getTaskState().value());
			taskStatePo.setMessage(task.getTaskState().label());
			result.add(taskStatePo);
		}
		stateDao.save(result); 
		logDao.save(transform(result));
	}


	public void update(StashUnitTask task) {
		DataStashUnitTaskStateLogPo taskStatePo = stateDao.findOne(task.getTaskProcId());
		Preconditions.checkNotNull(taskStatePo, "数据库状态任务和Flow内容有差别，需进行同步.");
		taskStatePo.setBrokerId(task.getBrokerId());
		taskStatePo.setBrokerIp(task.getBrokerIp());
		taskStatePo.setLastupd(new Date());
		taskStatePo.setState(task.getTaskState().value());
		taskStatePo.setMessage(task.getTaskState().label());
		stateDao.save(taskStatePo);
		logDao.save(transform(Lists.newArrayList(taskStatePo)));
	}
}
